#include "myjni.h"
#include "platform_config.h"
#include <pthread.h>
#include <cutils/properties.h>
#include <cutils/sockets.h>
#include <poll.h>
#include <ctype.h>
#include <stdio.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <string.h>
#define MAX_SELECT_TIME 10000000
extern pthread_mutex_t mutex_Gprs;
extern volatile int flag_login;
//从EEPROM提取终端ID,SIM卡号码，服务器IP地址及端口号，车牌号码
u8 g_csqValue = 0;
u8 g_weekCsqCounter = 0;
unsigned int AlreadyInNet = 0, GPRSLinKError = 0;
extern u8 oilvalstatus, sendtimes;
static u32 current4minad;
char format[20];
void UTC2China(u8* pdata);
extern u8 GPRS_RECEIVE[100];
u8 g_flagOfNewSMS = 0;
extern u32 RecodeCnter;
extern unsigned char GPRSLink_Flag;
extern SysInf *p_sys;
extern float   oilchangeval;
static int32_t GPRSSecondCounter = 0;
extern int fd_gprs;
unsigned char CheckModeOk = 0;
uint32_t SMSorCall = 0;                 //0---无 1_CALL 2_SMS
static u8 jianquan_len;
extern _GPSDATAREG   gpsdata;
static pthread_mutex_t mutex_send_data_lock = PTHREAD_MUTEX_INITIALIZER;
extern pthread_mutex_t mutex_gpsdata_lock;
uint16_t MinuteTemp;       //分钟计数器
extern SysInf  SysInfor;
extern int area_fd, priv_fd, gps_fd;
char iccid[PROPERTY_VALUE_MAX];
static volatile int new_area_data = 0;
static int send_data_error_count = 0;

void HEX_Print(char *buf, int len) {
	int ret = 0, i;
	char p[512] = { 0 };

	if (len > 255)
		return;
	for (i = 0; i < len; i++) {
		ret += sprintf(&p[ret], "%02x", buf[i]);
	}
	LOGE("%s", p);

}
//void Usart1_Printf(char *p, int len) {
//    LOGE("%s", p);
//}
void CHAR_Print(char *buf, int len) {
	int ret = 0, i;
	char printBuf[512] = { 0 };

	for (i = 0; i < len; i++) {
		ret += sprintf(printBuf + ret, "%c", buf[i]);
	}
	LOGE("%s", printBuf);

}

void reinitAt24c64() {
	int i;
	LOGE("%s 重新初始化存储器参数", __func__);
	write_log_to_sdcard("重新初始化存储器参数");
	memset((char *)&SysInfor, 0, sizeof(SysInfor));
	SysInfor.magic = 0xdeadbeef;
	sprintf((char*)SysInfor.IP, "39.98.33.207");
	SysInfor.port = 8282;
	sprintf((char*)SysInfor.terminalID, "9011201");
	sprintf((char*)&SysInfor.LocalPhoneNum1, "01861%s", (char*)SysInfor.terminalID);
	sprintf((char*)&SysInfor.CarNumber + 2, "K54321");
	SysInfor.CarNumber[0] = 0x8c;
	SysInfor.CarNumber[1] = 0x6b;
	sprintf((char*)&SysInfor.CarNumber_utf8, "豫K54321");
	SysInfor.EMPTY_AD_VALUE = 448;
	SysInfor.FULL_AD_VALUE = 590;
	SysInfor.EMPTY_COUNTER_VALUE = 13;
	SysInfor.STEP_DECEND_NUMBER = 9;
	SysInfor.AD_VALUE_BASE = 30;
	SysInfor.PER_STEPDECEND_ADVALUE = 4;
	SysInfor.WORKING_WIDTH = 500;
	SysInfor.CALC_AREA_DELAY_SECONDS = 0;
	stru_Linear *p = SysInfor.str_linearList;
	for (i = 0; i < 5; i++) {
		p[i].adValue = 4000 * (i + 1) / 5;
		p[i].literOfliquor = 30 * (i + 1) / 5;
	}
	SysInfor.version = 220;
	at24c64Write(priv_fd, SYSINFO_SET, (char *)&SysInfor, SysInfLength);
}


void Init_Terminal(void)
{
	int ret;

	memset(iccid, 0, sizeof(iccid));
	memset((char *)&SysInfor, 0, sizeof(SysInfor));
	checkExFile(); //first  check on system boot
	flag_login = 0;
	ret = at24c64Read(priv_fd, SYSINFO_SET, (void *)&SysInfor, SysInfLength);
	if ((SysInfor.magic != 0xdeadbeef) || (ret != 0)) {
		if (ret != 0)
			LOGE("读取at24c64失败");
		else
			LOGE("at24c64 magic error");
		reinitAt24c64();
	}
	property_set("rw.terminalID", SysInfor.terminalID);
	property_get("rw.iccid", iccid, "");
}



void UART1printfSysInfo(void)
{
	char Pinf[] = "      *******  Star  ********       ";
	char Sayinfo1[] = "LM-PPM-18A Version :2019-03-06-V1.9 ";
	char PNchar[] = "The terminalID is : ";
	char PNchar1[] = "The PhoneNum is : ";
	char IPInfochar[] = "The System IPAdress is :";
	char TheCarNumber[] = "The CarNumber is : ";
	char Pind[] = "      *******  END  *******     ";
	int i;

	Usart1_Printf((unsigned char *)Pinf, strlen(Pinf));
	Usart1_Printf((unsigned char *)Sayinfo1, strlen(Sayinfo1));
	Usart1_Printf((unsigned char *)PNchar, strlen(PNchar));
	Usart1_Printf((unsigned char *)SysInfor.terminalID, strlen(SysInfor.terminalID));
	Usart1_Printf((unsigned char *)PNchar1, strlen(PNchar1));
	Usart1_Printf((unsigned char *)SysInfor.LocalPhoneNum1, strlen(SysInfor.LocalPhoneNum1));
	Usart1_Printf((unsigned char *)IPInfochar, (strlen(IPInfochar)));
	Usart1_Printf((unsigned char *)SysInfor.IP, strlen(SysInfor.IP));
	LOGE("%s%s", TheCarNumber, SysInfor.CarNumber_utf8);
	LOGE("容器线性参数:");
	stru_Linear *p = SysInfor.str_linearList;
	for (i = 0; i < 5; i++) {
		LOGE("ad:%hd, liter:%hd", p[i].adValue, p[i].literOfliquor);
	}
	LOGE("测试参数:");
	LOGE("EMPTY_AD_VALUE:%hd\nFULL_AD_VALUE:%hd \nEMPTY_COUNTER_VALUE:%hd \nSTEP_DECEND_NUMBER:%hd \nAD_VALUE_BASE:%hd", SysInfor.EMPTY_AD_VALUE, SysInfor.FULL_AD_VALUE, SysInfor.EMPTY_COUNTER_VALUE, SysInfor.STEP_DECEND_NUMBER, SysInfor.AD_VALUE_BASE);
	Usart1_Printf((unsigned char *)Pind, strlen(Pind));
	write_log_to_sdcard("\r\n终端号:%s \r\n车牌号:%s \r\nIP:%s port:%d \r\n容器参数:\r\n%hd %hd, %hd %hd, %hd %hd, %hd %hd, %hd %hd\r\n测试参数:\r\nEMPTY_AD_VALUE:%hd\r\nFULL_AD_VALUE:%hd \r\nEMPTY_COUNTER_VALUE:%hd \r\nSTEP_DECEND_NUMBER:%hd \r\nAD_VALUE_BASE:%hd", SysInfor.terminalID, SysInfor.CarNumber_utf8, SysInfor.IP, SysInfor.port, p[0].adValue, p[0].literOfliquor, p[1].adValue, p[1].literOfliquor, p[2].adValue, p[2].literOfliquor, p[3].adValue, p[3].literOfliquor, p[4].adValue, p[4].literOfliquor, SysInfor.EMPTY_AD_VALUE, SysInfor.FULL_AD_VALUE, SysInfor.EMPTY_COUNTER_VALUE, SysInfor.STEP_DECEND_NUMBER, SysInfor.AD_VALUE_BASE);
}

void pwr_start() {
	SIM300_PWRON();
	// Delay(10);
}

void device_init(void)
{
	Init_Terminal();
	UART1printfSysInfo();

}

static void system_offline() {

	flag_login = 0;
	send_data_error_count = 0;
	write_log_to_sdcard("连续发送4次失败 系统离线");
}


void SaveAuthenticationCode(void)
{
	at24c64Write(priv_fd, SYSINFO_SET, (void *)&SysInfor, SysInfLength);
}


void GetAuthenticationCode(void) {
	u8 i;
	u8 numberOf0xff = 0;
	for (i = 0; i < 10; i++) {
		if (SysInfor.code_jianquan[i] == 0) {
			numberOf0xff++;//超过7个，判定为无鉴权码
		}
	}

	if (numberOf0xff > 7)//无鉴权码时，清零鉴权CODE,
	{
		memset(SysInfor.code_jianquan, 0, 11);
		jianquan_len = 0;
		LOGE("鉴权码为空");
	}
	else {
		jianquan_len = strlen(SysInfor.code_jianquan);
		if (jianquan_len > 10) {
			jianquan_len = 10;
		}
		LOGE("本地鉴权码");
	}
}

int socket_cli = -1, socket_err_count = 0;
int socket_init(void) {
	struct sockaddr_in server_addr;
	struct timeval timeo = { 3, 0 };

	if (socket_cli > 0) {
		shutdown(socket_cli, SHUT_RDWR);
		close(socket_cli);
		socket_cli = -1;
	}
	socket_cli = socket(AF_INET, SOCK_STREAM, 0);
	if (socket_cli <= 0) {
		LOGE("create socket fail[%s]", strerror(errno));
		return -1;
	}
	//设置服务器地址
	bzero(&server_addr, sizeof(server_addr));
	server_addr.sin_family = AF_INET;
	server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	server_addr.sin_port = htons(SysInfor.port);
	inet_pton(AF_INET, SysInfor.IP, &server_addr.sin_addr);
	LOGE("%s:ip=%s port=%d", __func__, SysInfor.IP, SysInfor.port);
	setsockopt(socket_cli, SOL_SOCKET, SO_SNDTIMEO, &timeo, (socklen_t)sizeof(timeo));
	int reuse = 1;
	setsockopt(socket_cli, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
	if (connect(socket_cli, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
		LOGE("%s connect fail[%d][%s]", __func__, errno, strerror(errno));
		goto out;
	}
	int block_flag = fcntl(socket_cli, F_GETFL);
	if (block_flag < 0) {
		LOGE("get socket fd flag error:%s\n", strerror(errno));
		goto out;
	}
	else {
		if (fcntl(socket_cli, F_SETFL, block_flag | O_NONBLOCK) < 0) {
			LOGE("set socket fd non block error:%s\n", strerror(errno));
			goto out;
		}
	}
	return 0;
out:
	shutdown(socket_cli, SHUT_RDWR);
	close(socket_cli);
	socket_cli = -1;
	return -errno;
}

static char socket_recv_buf[2048];

uint32_t GPRSDataSend(char *SendData, int len, long timeout_usec, int read_len, int area_data)//与服务器通信 7e 转7d 02
{
	int i;
	u8 *pstr;
	int j = 0;
	u8 *p;
	struct timeval tv;
	int ret = -1;

	pthread_mutex_lock(&mutex_send_data_lock);
	p = malloc(len * 2);
	if (socket_cli == -1 && socket_init() != 0) {
		LOGE("socket初始化失败");
		goto out;
	}
	pstr = p;
	*pstr = SendData[0];
	pstr++;
	for (i = 1; i<len - 1; i++)
	{
		if (SendData[i] == 0x7e)
		{
			*pstr = 0x7d;
			pstr++;
			*pstr = 0x02;
			j++;
		}
		else if (SendData[i] == 0x7d)
		{
			*pstr = 0x7d;
			pstr++;
			*pstr = 0x01;
			j++;
		}
		else
			*pstr = SendData[i];
		pstr++;

	}
	*pstr = SendData[len - 1];
	//LOGE("socket send[%d]:", len + j);
	HEX_Print((char *)p, len + j);
	int time_div = 0;
	int total_len = len + j;
	int send_len = send(socket_cli, p, total_len, 0);
	if (send_len != total_len) {
		LOGE("%s send fail, send_len=%d, err[%d][%s]", __func__, send_len, errno, strerror(errno));//104:Connection reset by peer, 32:Broken pipe
		goto out;
	}
	if (timeout_usec <= 0) {
		ret = 0;
		goto out;
	}
	ret = recv(socket_cli, socket_recv_buf, sizeof(socket_recv_buf), 0);
	if (ret > 0) {
		socket_err_count = 0;
		memcpy(SendData, socket_recv_buf, MIN(ret, read_len));
		LOGE("socket recv[%d]:", ret);
		HEX_Print(SendData, ret);
		goto out;
	}
	else {
		fd_set readfds;
		FD_ZERO(&readfds);
		FD_SET(socket_cli, &readfds);
		if (area_data) {//面积为重要数据,不能被打断
			time_div = 1;
		}
		else {
			timeout_usec /= (socket_err_count + 1);
			time_div = timeout_usec / 10000; //每次select 100毫秒
		}
		tv.tv_sec = timeout_usec / 1000000;
		tv.tv_usec = timeout_usec % 1000000;
		while (time_div) {
			ret = select(socket_cli + 1, &readfds, NULL, NULL, &tv); //阻塞,err:0 timeout err:-1 错误见errno
			if (ret > 0 && FD_ISSET(socket_cli, &readfds)) {
				ret = read(socket_cli, socket_recv_buf, sizeof(socket_recv_buf));
				if (ret > 0) {
					memcpy(SendData, socket_recv_buf, MIN(ret, read_len));
					socket_err_count = 0;
					LOGE("socket recv[%d]:", ret);
					HEX_Print(SendData, ret);
					goto out;
				}
				else {
					LOGE("socket recv unknown err[%s]", strerror(errno));
				}
			}
			else if (ret == 0) {//timeout
				LOGE("sendData, select timeout =%s", strerror(errno));
			}
			else if (ret < 0 && errno != EINTR) {
				LOGE("ret=%d, select timeout err=%s", ret, strerror(errno));
			}
			time_div--;
			if (new_area_data == 1)
				break;
		}
	}
out:
	free(p);
	pthread_mutex_unlock(&mutex_send_data_lock);
	if (errno == ECONNRESET || errno == EPIPE || (socket_err_count++ > 3)) {
		socket_err_count = 0;
		socket_init();
	}
	return ret;
}


u8 register_server()//0x0100注册
{
	u8 i;
	u32 num_temp;
	char format[13];
	u8 *pstr;
	u8 *pstr2;
	u8 *p;

	p = (u8 *)malloc(100); //终端注册
	pstr = p;

	*pstr = 0x7e;
	pstr++;
	*pstr = 0x01;
	pstr++;
	*pstr = 0x00;//注册ID

	pstr++;
	*pstr = 0x00;
	pstr++;
	//*pstr =0x2d;
	*pstr = 37 + strlen(SysInfor.CarNumber);
	pstr2 = (u8*)SysInfor.LocalPhoneNum1;
	LOGE("register Phone Number:%s,Car Number:%s,Terminal ID:%s", pstr2, SysInfor.CarNumber_utf8, SysInfor.terminalID);

	for (i = 0; i<6; i++)
	{
		strncpy(format, (char*)pstr2, 2);
		format[2] = 0;
		num_temp = atoi(format);
		pstr2 += 2;
		pstr++;
		*pstr = ((num_temp / 10) * 16 + num_temp % 10);
	}
	pstr++;
	*pstr = RecodeCnter % 0xffff / 0xff;
	pstr++;
	*pstr = RecodeCnter % 0xff;


	pstr++;
	*pstr = 0x0;
	pstr++;
	*pstr = 0x0;//省城ID
	pstr++;
	*pstr = 0x0;
	pstr++;
	*pstr = 0x0;//市城ID
	pstr++;
	strncpy((char*)pstr, "LMDZ", 5);
	pstr += 5;
	strncpy((char*)pstr, "2015.8.14 use 485\r\n", 20);
	pstr += 20;
	strncpy((char*)pstr, (char *)SysInfor.terminalID, 7);//终端ID
	pstr += 7;
	*pstr = 2;
	pstr++;
	strncpy((char*)pstr, SysInfor.CarNumber, strlen(SysInfor.CarNumber));
	pstr += strlen(SysInfor.CarNumber);

	*pstr = p[1];
	pstr2 = p;
	pstr2 += 2;

	for (i = 0; i<56; i++)
	{
		*pstr ^= *pstr2;
		pstr2++;

	}
	pstr++;
	*pstr = 0x7e;
	int len = GPRSDataSend((char *)p, 52 + strlen(SysInfor.CarNumber), MAX_SELECT_TIME, 99, 0);
	if (len > 0) {
		if ((p[0] == 0x7e) && (p[1] == 0x81) && (p[15] == 0))//终端注册应答
		{
			LOGE("$GSM reg ok!");
			jianquan_len = MIN((p[4] - 3), 10);
			pstr = (u8*)p;
			pstr += 16;
			for (i = 0; i<jianquan_len; i++)
			{
				SysInfor.code_jianquan[i] = *pstr;
				pstr++;
			}
			SaveAuthenticationCode();
			send_data_error_count = 0;
			free(p);
			return 1;
		}
	}
	if (++send_data_error_count > 4) {
		system_offline();
	}
	LOGE("服务器无响应[%d]:", len);
	free(p);

	return 0;

}

u8 authentication()//0x0x0102鉴权
{
	char format[13];
	u8 i;
	u32 temp_num;
	u8 *p;
	u8 *pstr;
	u8 *pstr2;
	p = malloc(100);
	pstr = p;
	*pstr = 0x7e;
	pstr++;
	*pstr = 0x01;
	pstr++;
	*pstr = 0x02;

	pstr++;
	*pstr = 0x00;
	pstr++;
	*pstr = jianquan_len;

	pstr2 = (u8 *)SysInfor.LocalPhoneNum1;
	for (i = 0; i<6; i++)
	{
		strncpy(format, (char*)pstr2, 2);
		format[2] = 0;
		temp_num = atoi(format);
		pstr2 += 2;
		pstr++;
		*pstr = ((temp_num / 10) * 16 + temp_num % 10);
	}
	pstr++;
	*pstr = RecodeCnter % 0xffff / 0xff;
	pstr++;
	*pstr = RecodeCnter % 0xff;
	pstr++;
	for (i = 0; i<jianquan_len; i++)
	{
		*pstr = SysInfor.code_jianquan[i];
		pstr++;
	}

	*pstr = p[1];
	pstr2 = p;
	pstr2 += 2;
	for (i = 0; i<(11 + jianquan_len); i++)
	{
		*pstr ^= *pstr2;
		pstr2++;

	}
	pstr++;
	*pstr = 0x7e;
	LOGE("$Send authentication:");

	//HEX_Print((char *)p, 25);
	int len = GPRSDataSend((char *)p, (15 + jianquan_len), MAX_SELECT_TIME, 99, 0);
	if ((len > 0) && (p[0] == 0x7e) && (p[1] == 0x80)) {//终端注册应答
		free(p);
		send_data_error_count = 0;
		return 1;
	}
	if (++send_data_error_count > 4) {
		system_offline();
	}
	LOGE("服务器无响应[%d]:", len);
	free(p);
	return 0;
}

u8 upload_verson()//0x0f15 版本信息上报
{
	u8 i;
	u32 temp_num;
	char format[13];
	u8 *pstr;
	u8 *pstr2;
	u8 *p;

	p = malloc(100);
	pstr = p; //终端注册

	*pstr = 0x7e;
	pstr++;
	*pstr = 0x0f;
	pstr++;
	*pstr = 0x15;//上传 版本信息
	pstr++;
	*pstr = 0x00;
	pstr++;
	*pstr = 0x36;

	pstr2 = (u8 *)SysInfor.LocalPhoneNum1;
	for (i = 0; i<6; i++)
	{
		strncpy(format, (char*)pstr2, 2);
		format[2] = 0;
		temp_num = atoi(format);
		pstr2 += 2;
		pstr++;
		*pstr = ((temp_num / 10) * 16 + temp_num % 10);
	}
	pstr++;
	*pstr = RecodeCnter % 0xffff / 0xff;
	pstr++;
	*pstr = RecodeCnter % 0xff;

	pstr++;
	*pstr = 0x03;

	pstr++;
	*pstr = 0x1;
	pstr++;
	*pstr = strlen("SIM900A-v1.02013/5/30");
	pstr++;
	strncpy((char*)pstr, "SIM900A-v1.02013/5/30", strlen("SIM900A-v1.02013/5/30"));

	pstr += strlen("SIM900A-v1.02013/5/30"); ;
	*pstr = 0x2;
	pstr++;
	*pstr = strlen("v1.0.0");
	pstr++;
	strncpy((char*)pstr, "v1.0.0", strlen("v1.0.0"));
	pstr += strlen("v1.0.0"); ;
	*pstr = 0x3;
	pstr++;
	//  *pstr = 7;
	//  pstr++ ;
	//  strncpy((char*)pstr,(char *)SysInfor.LocalPhoneNum,7);

	//  pstr+= 7;
	*pstr = 20;
	pstr++;
	property_get("rw.iccid", iccid, "");
	LOGE("iccid=%s", iccid);
	strncpy((char*)pstr, iccid, 20);

	pstr += 20;
	*pstr = p[1];
	pstr2 = p;
	pstr2 += 2;
	for (i = 0; i<65; i++)
	{
		*pstr ^= *pstr2;
		pstr2++;

	}
	pstr++;
	*pstr = 0x7e;
	LOGE("$Send Version:");
	//Usart1_Printf("\r\n",strlen("\r\n"));

	int len = GPRSDataSend((char *)p, 69, MAX_SELECT_TIME, 99, 0);
	if (len > 0 && p[0] == 0x7e && p[1] == 0x80) {
		free(p);
		send_data_error_count = 0;
		return 1;
	}
	if (++send_data_error_count > 4) {
		system_offline();
	}
	LOGE("服务器无响应[%d]:", len);
	free(p);

	return 0;
}


u8 stateOfLogin = 0;
u8 errorCounterOfAuthentication = 0;//鉴权失败次数
u8 g_reg_counter = 0;

//注册鉴权
void LoginAndAuthentication(void)
{
	if (jianquan_len == 0 && (SysInfor.code_jianquan[0] + SysInfor.code_jianquan[1]) == 0)
	{
		LOGE("获取鉴权码");
		stateOfLogin = register_server();//注册
	}
	else
	{
		stateOfLogin = 1;
	}
	if (stateOfLogin == 0)
	{
		if (++g_reg_counter>10)
		{
			g_reg_counter = 0;
			Usart1_Printf("$reg error!\r\n", strlen("\r\n$reg succed!\r\n"));
			//   SysRestart();//重启 sclu TODO
		}
	}
	else
	{
		usleep(1 * 1000 * 100);
		if (1 == authentication())//鉴权
		{
			Usart1_Printf("$authentication succed!", strlen("\r\n$authentication succed!\r\n"));
			flag_login = 1;
			write_log_to_sdcard("鉴权成功,系统上线");
			if (1 == upload_verson())//上传版本信息
			{
				Usart1_Printf("$upload_verson succed!", strlen("\r\n$upload_verson succed!\r\n"));

			}
			if (1 == plus())//心跳
			{
				LOGE("%s $plus succed", __func__);
			}
		}
		else
		{
			Usart1_Printf("$authentication error", strlen("\r\n$authentication error\r\n"));
			if (++errorCounterOfAuthentication >= 3)//超过3次，清空鉴权码
			{
				errorCounterOfAuthentication = 0;
				jianquan_len = 0;
				memset(SysInfor.code_jianquan, 0, sizeof(SysInfor.code_jianquan));
				SaveAuthenticationCode();
				stateOfLogin = 0;
			}
		}


	}
	LOGE("%s, %d", __func__, __LINE__);
}


u8 plus()//0x0002心跳
{
	char format[13];
	u8 i;
	u32 temp_num;
	u8 *p;

	u8 *pstr;
	u8 *pstr2;
	p = malloc(100);
	pstr = p;
	*pstr = 0x7e;
	pstr++;
	*pstr = 0x00;
	pstr++;
	*pstr = 0x02;

	pstr++;
	*pstr = 0x00;
	pstr++;
	*pstr = 0x00;

	pstr2 = (u8 *)SysInfor.LocalPhoneNum1;
	for (i = 0; i<6; i++)
	{
		strncpy(format, (char*)pstr2, 2);
		format[2] = 0;
		temp_num = atoi(format);
		pstr2 += 2;
		pstr++;
		*pstr = ((temp_num / 10) * 16 + temp_num % 10);
	}
	pstr++;
	*pstr = RecodeCnter % 0xffff / 0xff;
	pstr++;
	*pstr = RecodeCnter % 0xff;
	pstr++;

	*pstr = p[1];
	pstr2 = p;
	pstr2 += 2;
	for (i = 0; i<11; i++)
	{
		*pstr ^= *pstr2;
		pstr2++;

	}
	pstr++;
	*pstr = 0x7e;
	LOGE("$Send plus:");
	//HEX_Print((char *)p,15);

	int len = GPRSDataSend((char *)p, 15, MAX_SELECT_TIME, 99, 0);
	if (len > 0 && p[0] == 0x7e && p[1] == 0x80) {
		free(p);
		send_data_error_count = 0;
		return 1;
	}
	if (++send_data_error_count > 4) {
		system_offline();
	}
	LOGE("服务器无响应, len=%d", len);
	free(p);
	return 0;
}




void UTC2China(u8* pdata)
{
	u8 ChinaYear, ChinaMonth, ChinaDay, ChinaSeconds, ChinaMinutes, ChinaHour;

	ChinaYear = *pdata;
	ChinaMonth = *(pdata + 1);
	ChinaDay = *(pdata + 2);
	ChinaSeconds = *(pdata + 5);
	ChinaMinutes = *(pdata + 4);
	ChinaHour = (*(pdata + 3) + 8);

	if (ChinaHour>23)
	{
		ChinaHour -= 24;
		ChinaDay++;
		switch (ChinaMonth)
		{
		case 1:
			if (ChinaDay>31)
			{
				ChinaDay = 1;
				ChinaMonth++;
			}
			break;
		case 2:
			if ((0 == ChinaYear % 4 && 0 != ChinaYear % 100) || 0 == ChinaYear % 400)
			{
				if (ChinaDay>29)
				{
					ChinaDay = 1;
					ChinaMonth++;
				}
			}
			else
			{
				if (ChinaDay>28)
				{
					ChinaDay = 1;
					ChinaMonth++;
				}
			}
			break;
		case 3:
			if (ChinaDay>31)
			{
				ChinaDay = 1;
				ChinaMonth++;
			}
			break;
		case 4:
			if (ChinaDay>30)
			{
				ChinaDay = 1;
				ChinaMonth++;
			}
			break;
		case 5:
			if (ChinaDay>31)
			{
				ChinaDay = 1;
				ChinaMonth++;
			}
			break;
		case 6:
			if (ChinaDay>30)
			{
				ChinaDay = 1;
				ChinaMonth++;
			}
			break;
		case 7:
			if (ChinaDay>31)
			{
				ChinaDay = 1;
				ChinaMonth++;
			}
			break;
		case 8:
			if (ChinaDay>31)
			{
				ChinaDay = 1;
				ChinaMonth++;
			}
			break;
		case 9:
			if (ChinaDay>30)
			{
				ChinaDay = 1;
				ChinaMonth++;
			}
			break;
		case 10:
			if (ChinaDay>31)
			{
				ChinaDay = 1;
				ChinaMonth++;
			}
			break;
		case 11:
			if (ChinaDay>30)
			{
				ChinaDay = 1;
				ChinaMonth++;
			}
			break;
		case 12:
			if (ChinaDay>31)
			{
				ChinaDay = 1;
				ChinaMonth = 1;
				ChinaYear++;
			}
			break;
		default:break;
		}
	}
	*(pdata) = ((ChinaYear / 10) * 16 + ChinaYear % 10);
	*(pdata + 1) = ((ChinaMonth / 10) * 16 + ChinaMonth % 10);
	*(pdata + 2) = ((ChinaDay / 10) * 16 + ChinaDay % 10);
	*(pdata + 5) = ((ChinaSeconds / 10) * 16 + ChinaSeconds % 10);
	*(pdata + 4) = ((ChinaMinutes / 10) * 16 + ChinaMinutes % 10);
	*(pdata + 3) = ((ChinaHour / 10) * 16 + ChinaHour % 10);

}


static void getTime(char *buf) {
	time_t timep;
	time(&timep);

	struct tm * ptm;
	long ts;
	char str[20];

	ts = time(NULL);
	ptm = localtime(&ts);

	int y, month, d, h, m, s, week;
	y = ptm->tm_year + 1900 - 2000;
	month = ptm->tm_mon + 1;
	d = ptm->tm_mday;
	h = ptm->tm_hour - 8;
	m = ptm->tm_min;
	s = ptm->tm_sec;
	//struct tm * tm = gmtime(&timep);
	//week = tm->tm_wday;

	buf[0] = (char)y;
	buf[1] = (char)month;
	buf[2] = (char)d;
	buf[3] = (char)h;
	buf[4] = (char)m;
	buf[5] = (char)s;
	//LOGE("current y=%d, month=%d, d = %d, h:%d, m:%d, s:%d\n", buf[0], buf[1], buf[2], buf[3], buf[4], buf[5]); 
}

void sendAreaData(unsigned int area, unsigned short areaRate, unsigned short pesticide, unsigned short seconds)
{
	u8 flag_GPS;

	u8 i;
	u8 * p_time;
	char * pstr;
	char *pstr2;
	u32 wei;
	u32 jing;
	u32 temp_num;
	u8 * Pdata;
	char p[47];
	//u32 area_temp = g_areaOfFarmland*1000;


	new_area_data = 1;
	pstr = p;
	memset(pstr, 0, 47);


	*pstr = 0x7e;
	pstr++;
	*pstr = 0x09;
	pstr++;
	*pstr = 0x00;//上传

	pstr++;
	*pstr = 0x00;
	pstr++;
	*pstr = 32;

	pstr2 = (char *)SysInfor.LocalPhoneNum1;

	for (i = 0; i < 6; i++)
	{
		strncpy(format, pstr2, 2);
		format[2] = 0;
		temp_num = atoi(format);
		pstr2 += 2;
		pstr++;
		*pstr = ((temp_num / 10) * 16 + temp_num % 10);
	}
	pstr++;
	*pstr =( RecodeCnter & 0xffff) >>8;
	pstr++;
	*pstr = RecodeCnter ;
	Pdata = (u8*)pstr;
	Pdata += 1;
	*Pdata = 0xf3;	//消息类型0xf1为收割机,0xf2为深耕机, 0xf3植保机
	Pdata += 1;
	*Pdata = 0x01;	//协议版本号


					//gps信息
	wei = (u32)(g_currentLatitude * 1000000);//维度
	Pdata++;
	*Pdata = (wei >> 24);
	Pdata++;
	*Pdata = (wei >> 16);
	Pdata++;
	*Pdata = (wei >> 8);;
	Pdata++;
	*Pdata = wei ;

	jing = (u32)(g_currentLongitude * 1000000);//经度
	Pdata++;
	*Pdata = (jing >> 24);
	Pdata++;
	*Pdata = (jing >> 16);
	Pdata++;
	*Pdata = (jing >> 8);
	Pdata++;
	*Pdata = jing ;

	Pdata++;
	*Pdata = 0;//高度 1
	Pdata++;
	*Pdata = 0; //高度 1

	temp_num = (u16)(10 * gps_speed);
	Pdata++;
	*Pdata = temp_num >>8;
	Pdata++;
	*Pdata = temp_num ;//填充 速度

	temp_num = (u16)gps_bearing;
	Pdata++;
	*Pdata = temp_num >>8;
	Pdata++;
	*Pdata = temp_num ;//角度

	Pdata++;
	p_time = Pdata;
	*Pdata = gps_year % 100;//year
	Pdata++;
	*Pdata = gps_mon % 100;//month
	Pdata++;
	*Pdata = gps_day % 100;//date
	Pdata++;
	*Pdata = gps_hour % 100;//hour
	Pdata++;
	*Pdata = gps_min % 100;//minute
	Pdata++;
	*Pdata = gps_sec % 100; //second
	UTC2China(p_time);//整理时间格式	


	Pdata++;
	*Pdata = area >> 24;//
	Pdata++;
	*Pdata = area >> 16;//
	Pdata++;
	*Pdata = area >> 8;//
	Pdata++;
	*Pdata = area;//面积，保留三个小数点，单位亩
	Pdata++;
	*Pdata = (pesticide / 5) >> 8;//
	Pdata++;
	*Pdata = pesticide / 5;//
	Pdata++;
	*Pdata = seconds >> 8;//
	Pdata++;
	*Pdata = seconds;//  产量，保留三个小数点，单位千克

	Pdata++;
	*Pdata = areaRate >> 8;//    面积合格率高位
	Pdata++;
	*Pdata = areaRate;//   面积合格率低位
	Pdata++;
	*Pdata = p[1];
	pstr2 = p;
	pstr2 += 2;
	for (i = 0; i < 43; i++)
	{
		*Pdata ^= *pstr2;
		pstr2++;

	}
	Pdata++;
	*Pdata = 0x7e;
	int len = GPRSDataSend(p, 47, MAX_SELECT_TIME, 46, 1);
	new_area_data = 0;
	if (len > 0 && p[0] == 0x7e && p[1] == 0x80) {
		LOGE("发送面积数据成功");
		write_log_to_sdcard("发送面积数据成功");
		send_data_error_count = 0;
	}
	else {
		LOGE("发送面积数据失败，保存为离线数据");
		write_log_to_sdcard("发送面积数据失败，保存为离线数据");
		if (++send_data_error_count > 4) {
			system_offline();
		}
		save_area_data(p);
	}
}

static char xor_gen(char *buf, int len) {
	int i;
	char result, *temp;

	result = buf[1];
	temp = buf;
	temp += 2;
	for (i = 0; i < len; i++) {
		result ^= *temp;
		temp++;
	}
	return result;
}

static char gen_xor(char *buf, int len) {
	char start = buf[0];
	int i;

	for (i = 1; i < len; i++)
		start ^= buf[i];

	return start;
}

static int sendAreaErrorCount = 0;
u8 sendOfflineArea(void)//发送面积和重量,加油，维修指令
{
	int i, ret = AREA_DATA_NONE;
	char *p = malloc(47);

	if (read_area_data(p)) {
		ret = AREA_DATA_NONE;
		goto out;
	}

	if ((p[0] != p[46]) || (p[0] != 0x7e)) {
		LOGE("数据头错误，跳过该条离线数据");
		write_log_to_sdcard("面积数据头错误，跳过该条离线数据");
		ret = AREA_DATA_SKIP;
		goto out;
	}
	if (gen_xor(p + 1, 44) != p[45]) {
		write_log_to_sdcard("面积数据校验错误，跳过该条离线数据");
		ret = AREA_DATA_SKIP;
		goto out;
	}
	//HEX_Print(p, 47);
	int len = GPRSDataSend(p, 47, MAX_SELECT_TIME, 46, 1);
	if (len > 0 && p[0] == 0x7e && p[1] == 0x80) {
		sendAreaErrorCount = 0;
		send_data_error_count = 0;
		ret = AREA_DATA_SUCCESS;
	}
	else {
		ret = AREA_DATA_ERROR;
	}
	if (++send_data_error_count > 4) {
		system_offline();
	}
	LOGE("服务器无响应, len=%d", len);
	if (sendAreaErrorCount++ > 10) {
		sendAreaErrorCount = 0;
		write_log_to_sdcard("面积发送10次失败，跳过该数据");
		ret = AREA_DATA_SKIP;
	}
out:
	free(p);
	return ret;
}

u8 report_locat(int work_state, unsigned char adc_value)//0x0200 位置信息
{
	u8 flag_GPS;
	u8 i, ret = 0;
	u32 wei;
	u32 jing;
	u32 temp_num;
	u8 * Pdata;
	u8 * p_time;

	u8 *pstr;
	u8 *pstr2;
	u8 *p;

	p = malloc(100);
	pstr = p; //终端注册


	*pstr = 0x7e;
	pstr++;
	*pstr = 0x02;
	pstr++;
	*pstr = 0x00;//位置信息
	pstr++;
	*pstr = 0x00;
	pstr++;
	*pstr = 0x1F;

	pstr2 = (u8*)SysInfor.LocalPhoneNum1;
	//LOGE("Phone Number:%s,Car Number:%s,Terminal ID:%s", pstr2, SysInfor.CarNumber_utf8, SysInfor.terminalID);
	for (i = 0; i < 6; i++)
	{
		strncpy(format, (char*)pstr2, 2);
		format[2] = 0;
		temp_num = atoi(format);
		pstr2 += 2;
		pstr++;
		*pstr = ((temp_num / 10) * 16 + temp_num % 10);
	}
	pstr++;
	*pstr = (RecodeCnter & 0xffff) >>8;
	pstr++;
	*pstr = RecodeCnter ;
	pstr++;
	*pstr = 0x0;
	pstr++;
	*pstr = 0x0;
	pstr++;
	*pstr = 0x0;
	pstr++;
	*pstr = 0x0;//报警标志位

	pstr++;
	*pstr = 0x00;
	pstr++;
	if (flag_GPS == 1) *pstr = 0x04;
	else  *pstr = 0x00;
	pstr++;
	*pstr = 0x00;
	pstr++;
	*pstr = 0x03;// 状态

	Pdata = pstr;

	//gps信息
	wei = (u32)(g_currentLatitude * 1000000);//维度
	Pdata++;
	*Pdata = (wei >> 24);
	Pdata++;
	*Pdata = (wei >> 16);
	Pdata++;
	*Pdata = (wei >> 8);;
	Pdata++;
	*Pdata = wei ;

	jing = (u32)(g_currentLongitude * 1000000);//经度
	Pdata++;
	*Pdata = (jing >> 24);
	Pdata++;
	*Pdata = (jing >> 16);
	Pdata++;
	*Pdata = (jing >> 8);
	Pdata++;
	*Pdata = jing ;

	Pdata++;
	*Pdata = 0;//高度 1
	Pdata++;
	*Pdata = 0; //高度 1

	temp_num = (u16)(10 * gps_speed);
	Pdata++;
	*Pdata = temp_num >>8;
	Pdata++;
	*Pdata = temp_num;//填充 速度

	temp_num = (u16)gps_bearing;
	Pdata++;
	*Pdata = temp_num >>8;
	Pdata++;
	*Pdata = temp_num ;//角度

	Pdata++;
	p_time = Pdata;
	*Pdata = gps_year % 100;//year
	Pdata++;
	*Pdata = gps_mon % 100;//month
	Pdata++;
	*Pdata = gps_day % 100;//date
	Pdata++;
	*Pdata = gps_hour % 100;//hour
	Pdata++;
	*Pdata = gps_min % 100;//minute
	Pdata++;
	*Pdata = gps_sec % 100; //second
	UTC2China(p_time);//整理时间格式

	Pdata++;
	//----30 01 XX---//
	*Pdata = 0x30;
	Pdata++;
	*Pdata = work_state;
	Pdata++;
	// LOGE("%s %d", __func__, __LINE__);
	*Pdata = adc_value;
	// LOGE("%s %d", __func__, __LINE__);
	Pdata++;
	//----30 01 XX---//
	*Pdata = p[1];
	pstr2 = p;
	pstr2 += 2;
	for (i = 0; i < 42; i++)//39
	{
		*Pdata ^= *pstr2;
		pstr2++;

	}
	Pdata++;
	*Pdata = 0x7e;
	// LOGE("%s %d", __func__, __LINE__);
	LOGE("%s:", __func__);
	//HEX_Print((char *)p, 46);//43
	int len = GPRSDataSend((char *)p, 46, MAX_SELECT_TIME, 99, 0);//43
	if (len > 0 && p[0] == 0x7e && p[1] == 0x80) {
		free(p);
		send_data_error_count = 0;
		return 1;
	}
	if (++send_data_error_count > 4) {
		system_offline();
	}
	LOGE("服务器无响应, len=%d", len);
	free(p);
	return 0;
}

